# -*- coding: utf-8 -*-

class State:
    pass

class Idle(State):
    pass

class Hover(State):
    pass

class Active(State):
    pass

class Visited(State):
    pass

class Attribute:

    def __init__(self, name, value='', space=None):
        self.name = name
        self.value = value
        self.space = space

    def __str__(self):
        return '{}: {}'.format(self.name, self.value)

class Element(list):
    
    def __init__(self, name, kids=[], state=Idle, space=None, parent=None):
        self.name = name
        self += kids
        for kid in self:
            if isinstance(kid, Element):
                kid.parent = self
        self.state = state
        self.space = space
        self.parent = self if not parent else parent

    def filter(self, func=(lambda x: True), selftoo=False, walk=False):
        if selftoo and func(self):
            yield self
        for node in self:
            try:
                if func(node):
                    yield node
                if walk:
                    for kid in node.filter(func, False, True):
                        yield kid
            except AttributeError:
                continue

    def state(self, state=None):
        if isinstance(state, State):
            self.state = state
        return self.state

    def attr(self, name):
        for attribute in self.filter(lambda x: isinstance(x, Attribute)):
            if attribute.name == name:
                return attribute

    def __str__(self):
        attrs = ''
        elements = ''
        for node in self:
            if isinstance(node, Attribute):
                attrs += str(node) + ', '
            else:
                elements += str(node) + '\n'
        elements = '    ' + elements.replace('\n', '\n    ')
        return 'ELEMENT {} ({}) :\n{}'.format(self.name, attrs[:-2],
                                              elements[:-1])

tree = Element('html', [
    Attribute('lang', 'fr'),
    Element('head', [
        Element('title', []),
        Element('link', [
            Attribute('rel', 'stylesheet'),
            Attribute('type', 'text/css'),
            Attribute('href', 'tester.css')
            ])
        ]),
    Element('body', [
        Element('h1', ['Title of the test document']),
        Element('p', [
            'This is the first paragraph. No class.',
            Attribute('id', 'para2')
            ]),
        Element('p', [
            Attribute('class', 'last'),
            'This is the last paragraph.'
            ])
        ])
])

if __name__ == '__main__':
    print(tree)
